/// @tags: OverallDiv
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <stack>

using namespace std;

namespace BlueQuantum {

typedef long long LL;

int const N = 2e5 + 5;

int n, m, q, e_cnt, q_cnt;
int opt[N], a[N], b[N], key[N];
LL ans[N * 2], s[N], hash[N * 3];
map<int, int> mp[N];

struct Edge {
  int u, v, t;
} e[N * 2], q1[N * 2], q2[N * 2];

struct Event {
  int a, b, t, opt;
  inline bool operator<(Event const &rhs) const {
    return t == rhs.t ? opt < rhs.opt : t < rhs.t;
  }
} eve[N * 2];

namespace SegmentTree {

int cnt;
int root[N];

struct Node {
  int ls, rs, siz;
  LL sum;
} tr[N * 20];

void modify(int &x, int l, int r, int k, int v) {
  if (x == 0) x = ++cnt;
  tr[x].siz += v, tr[x].sum += v * hash[k];
  if (l == r) return;
  int mid = (l + r) >> 1;
  k <= mid ? modify(tr[x].ls, l, mid, k, v) : modify(tr[x].rs, mid + 1, r, k, v);
}

void merge(int &x, int y) {
  if (!(x && y)) return void(x |= y);
  merge(tr[x].ls, tr[y].ls);
  merge(tr[x].rs, tr[y].rs);
  tr[x].sum += tr[y].sum;
  tr[x].siz += tr[y].siz;
}

LL query(int x, int l, int r, int k) {
  if (l == r) return (LL)k * hash[l];
  int mid = (l + r) >> 1;
  return k <= tr[tr[x].rs].siz
             ? query(tr[x].rs, mid + 1, r, k)
             : tr[tr[x].rs].sum + query(tr[x].ls, l, mid, k - tr[tr[x].rs].siz);
}

}  // namespace SegmentTree

using SegmentTree::root;

namespace PersistedStack {

struct Node {
  int x, dep;
};

int dep[N], f[N];
stack<Node> stk;

int find(int x) { return f[x] == x ? x : find(f[x]); }

inline void merge(int x, int y) {
  x = find(x), y = find(y);
  if (x != y) {
    if (dep[x] < dep[y]) swap(x, y);
    f[y] = x;
    stk.push((Node){y, dep[x] == dep[y]});
    dep[x] += dep[x] == dep[y];
  }
}

}  // namespace PersistedStack

using PersistedStack::dep;
using PersistedStack::f;

using PersistedStack::find;

namespace Tarjan {

using PersistedStack::merge;

int cnt, e_cnt;
int dfn[N], low[N], heads[N];
bool ins[N];
stack<int> stk;

struct Edge {
  int v, nxt;
} e[N * 2];

inline void add(int u, int v) {
  e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt;
}

void tarjan(int u) {
  dfn[u] = low[u] = ++cnt;
  ins[u] = true;
  stk.push(u);
  for (int i = heads[u], v; i; i = e[i].nxt) {
    if (dfn[v = e[i].v] == 0) {
      tarjan(v);
      low[u] = min(low[u], low[v]);
    } else if (ins[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (dfn[u] == low[u]) {
    int tmp;
    do {
      tmp = stk.top();
      merge(tmp, u);
      ins[tmp] = false;
      stk.pop();
    } while (tmp != u);
  }
}

}  // namespace Tarjan

using Tarjan::dfn;

using Tarjan::add;
using Tarjan::tarjan;

void solve(int l, int r, int ql, int qr) {
  if (ql > qr) return;
  if (l == r) {
    for (int i = ql; i <= qr; ++i) e[i].t = l;
    return;
  }
  int n_cnt = 0, mid = (l + r) >> 1;
  size_t top = PersistedStack::stk.size();
  for (int i = ql, u, v; i <= qr; ++i)
    if (e[i].t <= mid) {
      u = find(e[i].u), v = find(e[i].v);
      key[++n_cnt] = u, key[++n_cnt] = v;
      add(u, v);
    }
  for (int i = 1; i <= n_cnt; ++i)
    if (!dfn[key[i]]) tarjan(key[i]);
  int cnt1 = 0, cnt2 = 0;
  for (int i = ql; i <= qr; ++i) {
    (find(e[i].u) == find(e[i].v) && e[i].t <= mid) ? q1[++cnt1] = e[i]
                                                    : q2[++cnt2] = e[i];
  }
  for (int i = 1; i <= cnt1; ++i) e[ql + i - 1] = q1[i];
  for (int i = 1; i <= cnt2; ++i) e[ql + cnt1 + i - 1] = q2[i];
  Tarjan::e_cnt = Tarjan::cnt = 0;
  for (int i = 1; i <= n_cnt; ++i)
    Tarjan::heads[key[i]] = Tarjan::dfn[key[i]] = Tarjan::low[key[i]] = 0;
  solve(mid + 1, r, ql + cnt1, qr);
  while (PersistedStack::stk.size() != top) {
    int tmp = PersistedStack::stk.top().x;
    PersistedStack::dep[f[tmp]] -= PersistedStack::stk.top().dep;
    PersistedStack::f[tmp] = tmp;
    PersistedStack::stk.pop();
  }
  solve(l, mid, ql, ql + cnt1 - 1);
}

inline void merge(int x, int y) {
  x = find(x), y = find(y);
  if (x != y) {
    if (dep[x] < dep[y]) swap(x, y);
    f[y] = x;
    dep[x] += (dep[y] == dep[x]);
    SegmentTree::merge(root[x], root[y]);
  }
}

inline int getVal(LL x) { return lower_bound(hash + 1, hash + *hash + 1, x) - hash; }

inline int main() {
  cin >> n >> m >> q;
  for (int i = 1; i <= n; ++i) cin >> hash[i], s[i] = hash[i], ++*hash;
  for (int i = 1; i <= m; ++i) {
    cin >> e[i].u >> e[i].v;
    mp[e[i].u][e[i].v] = i;
  }
  for (int i = 1; i <= q; ++i) {
    cin >> opt[i] >> a[i] >> b[i];
    switch (opt[i]) {
      case 1:
        e[mp[a[i]][b[i]]].t = q - i + 1;
        break;
      case 2:
        s[a[i]] += b[i];
        hash[++*hash] = s[a[i]];
        eve[++q_cnt] = (Event){a[i], b[i], q - i + 1, opt[i]};
        break;
      case 3:
        eve[++q_cnt] = (Event){a[i], b[i], q - i + 1, opt[i]};
    }
  }
  for (int i = 1; i <= n; ++i) PersistedStack::f[i] = i;
  sort(hash + 1, hash + *hash + 1);
  *hash = unique(hash + 1, hash + *hash + 1) - hash - 1;
  for (int i = 1; i <= n; ++i) SegmentTree::modify(root[i], 1, *hash, getVal(s[i]), 1);
  solve(0, q + 1, 1, m);
  for (int i = 1; i <= m; ++i) eve[++q_cnt] = (Event){e[i].u, e[i].v, e[i].t, 1};
  sort(eve + 1, eve + q_cnt + 1);
  memset(ans, -1, sizeof(ans));
  for (int i = 1; i <= n; ++i) PersistedStack::f[i] = i, PersistedStack::dep[i] = 0;
  for (int i = 1, x, y; i <= q_cnt; ++i) {
    switch (eve[i].opt) {
      case 1:
        merge(eve[i].a, eve[i].b);
        break;
      case 2:
        x = eve[i].a;
        y = find(x);
        SegmentTree::modify(root[y], 1, *hash, getVal(s[x]), -1);
        s[x] -= eve[i].b;
        SegmentTree::modify(root[y], 1, *hash, getVal(s[x]), 1);
        break;
      case 3:
        x = find(eve[i].a);
        ans[q - eve[i].t + 1] = SegmentTree::query(
            root[x], 1, *hash, min(eve[i].b, SegmentTree::tr[root[x]].siz));
    }
  }
  for (int i = 1; i <= q; ++i)
    if (ans[i] != -1) cout << ans[i] << '\n';
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("P5163 WD与地图.in", "r", stdin);
  freopen("P5163 WD与地图.out", "w", stdout);
#endif
#endif

  ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}
